package com.example.mykotlin.base.config

import com.example.mykotlin.base.flex.MyInsertUpdateListener
import com.example.mykotlin.base.flex.YitterKeyGenerator
import com.example.mykotlin.base.util.tryOnly
import com.mybatisflex.core.FlexGlobalConfig
import com.mybatisflex.core.keygen.KeyGeneratorFactory
import com.mybatisflex.core.mybatis.FlexConfiguration
import com.mybatisflex.spring.boot.ConfigurationCustomizer
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer
import org.apache.ibatis.logging.stdout.StdOutImpl
import org.springframework.context.annotation.Configuration
import org.springframework.core.io.Resource
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.core.io.support.ResourcePatternResolver
import org.springframework.core.type.classreading.CachingMetadataReaderFactory
import org.springframework.core.type.classreading.MetadataReader
import org.springframework.core.type.classreading.MetadataReaderFactory
import org.springframework.util.ClassUtils


@Configuration
class MyConfigurationCustomizer : ConfigurationCustomizer, MyBatisFlexCustomizer {
    override fun customize(configuration: FlexConfiguration) {
        configuration.logImpl = StdOutImpl::class.java
    }

    override fun customize(globalConfig: FlexGlobalConfig) {
        tryOnly {
            KeyGeneratorFactory.register("YitterID", YitterKeyGenerator())
        }
        tryOnly {
            //指定数据库表的的实体类所在的包位置（mybatis-flex）
            //全局配置注册数据填充监听器
            val entityPackagePath =  "com.example.mykotlin.model.entity"
            val resourcePatternResolver: ResourcePatternResolver = PathMatchingResourcePatternResolver()
            val metadataReaderFactory: MetadataReaderFactory = CachingMetadataReaderFactory(resourcePatternResolver)
            // 加载系统所有类资源
            val resources: Array<Resource> = resourcePatternResolver.getResources(
                ("classpath:" + entityPackagePath.replace(
                    "\\.".toRegex(),
                    "/"
                )) + "/**/*.class"
            )
            val list: ArrayList<Class<*>> = ArrayList()
            // 把每一个class文件找出来
            for (r in resources) {
                val metadataReader: MetadataReader = metadataReaderFactory.getMetadataReader(r)
                val clazz: Class<*> = ClassUtils.forName(metadataReader.classMetadata.className, null)
                list.add(clazz)
            }
            val toArray: Array<Class<*>> = Array(list.size) { list[it] }
            val listener = MyInsertUpdateListener()
            globalConfig.registerInsertListener(listener, *toArray)
            globalConfig.registerUpdateListener(listener, *toArray)
        }

    }
}